home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / 80X86 / DOS32V33.ZIP / LIB / VESA.ASM < prev    next >
Encoding:
Assembly Source File  |  1995-11-16  |  14.7 KB  |  493 lines

  1. comment ~
  2. *****************************************************************************
  3.                  VESA library containing three basic functions
  4.  
  5.  
  6. File:    VESA.ASM
  7. Author:  Adam Seychell
  8. System:  DOS32
  9. Version: 1.00
  10.  
  11.  
  12.  
  13.     This library uses the VBE protected mode interface (func 0Ah) to obtain
  14. an near pointer directly calling the 32bit VBE funcs 05h and 07h.
  15. Calling the 32bit functions directly removes overhead of having to emulating
  16. a real mode interrupt and I have measured it to be over 15 times faster!
  17. My friends P90 rates over a 50 times speed increase!
  18.    Currently very few video cards are supporting the new protected mode
  19. interface of the VBE v2.0 interface. An excellent VESA driver is availible
  20. for just about all video cards and is called UniVBE. Versions 5.1+ of
  21. UniVBE support the VBE 2.0 protected mode interface allowing ultrafast
  22. VBE function calls in SVGA modes and if your card is Vesa Loacal bus
  23. or PCI bus you can use the linear frame buffer and avoid bank switching
  24. all togehter.
  25.  
  26.  
  27. To set the bank or start address use the macros SetBank and SetStart
  28. defined in VESA.INC.
  29.  
  30. *****************************************************************************
  31. Function:   CheckVbeMode
  32. Expects:    Eax = VESA video mode number (bits 16..31 ignored).
  33.                   If bit 14 set then use linear memory mapping.
  34. Returns:  if successful;
  35.              EAX = near pointer to video address
  36.              Carry = 0
  37.           if unsuccessful;
  38.              EAX = zero
  39.              Carry = 1
  40.              DL = error code.   1 = VBE not installed
  41.                                 2 = mode not supported.
  42.                                 3 = mode incompatible.
  43. Description: Checks to see if the VBE video mode can be used. if so then
  44.              will return a pointer to video mapping address.
  45. Notes:    *   All registers are preserved.
  46.           *   If linear frame buffer is selected then EAX will point to
  47.               the linear frame buffer. The SetBank macro function is
  48.               undefined and should not be used.
  49.  
  50. *****************************************************************************
  51. Function:   SetVbeMode
  52. Expects:    Nothing.
  53. Returns:    Nothing.
  54. Description: Set video mode to the mode number specified to last successful
  55.              call to CheckVbeMode.
  56. Notes:       All registers are preserved.
  57.  
  58. *****************************************************************************
  59. Function:   VbeFunc06
  60.  
  61.    Input:   BL   = 00h          Set Scan Line Length in Pixels
  62.                  = 01h          Get Scan Line Length
  63.                  = 02h          Set Scan Line Length in Bytes
  64.                  = 03h          Get Maximum Scan Line Length
  65.             CX   =         If BL=00h  Desired Width in Pixels
  66.                            If BL=02h  Desired Width in Bytes
  67.                            (Ignored for Get Functions)
  68.  
  69. Output:     AX   =         VBE Return Status
  70.             BX   =         Bytes Per Scan Line
  71.             CX   =         Actual Pixels Per Scan Line
  72.                            (truncated to nearest complete pixel)
  73.             DX   =         Maximum Number of Scan Lines
  74. Description: VBE Function 06h - Set/Get Logical Scan Line Length
  75.  
  76. Notes:       directly calls INT 10h AX=4F06h;
  77.              Calling this function saves the "Bytes Per Scan Line" returned
  78.              in BX which is required for correct operation of the
  79.              SetStart macro.
  80.  
  81. *****************************************************************************
  82. ~
  83. .386
  84. .MODEL FLAT , C
  85.  
  86. Include vesa.inc
  87.  
  88. _BSS SEGMENT
  89. PmodeSetStart           DD ?
  90. file_buffer             DD ?
  91. ProgramBaseAddress      DD ?
  92. _BankSetTable           DD 128 DUP (?)
  93. VideoModeNumber         DW ?
  94. Total64Kbocks           DW ?
  95. Current_Bank            DB ?
  96. VBE_StarPerPixelFactor  DB ?
  97. DOS_segs LABEL DWORD
  98. Real_ES     DW  ?
  99. Real_DS     DW  ?
  100.  
  101. _BSS ENDS
  102.  
  103. .CODE
  104.  
  105. align 4
  106. VBE_BytesPerScanLine    DD 0
  107. VbeSetBank              DD Offset SetBank_RealMode
  108. VbeSetStart             DD Offset SetStart_RealMode
  109. Old_PhysBasePtr         DD -1
  110.  
  111.  
  112.  
  113. ;--------------------------------------------------------
  114. ; Call real mode set video bank function
  115. ; Note: very very slow....
  116. ;----------------------------------------------------------
  117. SetBank_RealMode PROC
  118.         push   ebx
  119.         xor    ebx,ebx
  120.         mov    ax,04F05h
  121.         int    10h
  122.         pop    ebx
  123.         Ret
  124. SetBank_RealMode ENDP
  125.  
  126.  
  127. ;--------------------------------------------------------
  128. ; Call real mode set display start bank function
  129. ; CX=pixel in scan line
  130. ; DX=scan line number
  131. ; Note: very very slow....
  132. ;----------------------------------------------------------
  133. SetStart_RealMode PROC
  134.         push   ebx
  135.         xor    ebx,ebx
  136.         mov    ax,04F07h
  137.         int    10h
  138.         pop    ebx
  139.         Ret
  140. SetStart_RealMode ENDP
  141.  
  142.  
  143. ;--------------------------------------------------------
  144. ; Call Protected mode set display start bank function
  145. ; ECX=pixel in scan line
  146. ; EDX=scan line number
  147. ;----------------------------------------------------------
  148. SetStart_ProtectedMode PROC
  149.         push   ebx
  150.         xor    ebx,ebx
  151.         imul   edx,[VBE_BytesPerScanLine]
  152.         add    edx,ecx
  153.         mov    cl,[VBE_StarPerPixelFactor]
  154.         shr    edx,cl
  155.         mov    cx,dx
  156.         shr    edx,16
  157.         mov    ax,04F07h
  158.         Call   [PmodeSetStart]
  159.         pop    ebx
  160.         Ret
  161. SetStart_ProtectedMode ENDP
  162.  
  163.  
  164. ;------------------------------------------------------------
  165. ; Procudure to call a DOS interrupt.
  166. ;
  167. ; Expects the intrrupt number pushed on the stack.
  168. ;
  169. ;  e.g    push  10h
  170. ;         call  DOSinterrupt
  171. ;         jc   error
  172. ; Real mode ES and DS registers are passed via varibles Real_ES and Real_DS.
  173. ;
  174. ;
  175. ; As explained in the DOS32 documentaion, DOS32 initally handles all interrupts
  176. ; such that calling a protected mode interrupt will automatically call
  177. ; the same interrupt number in real mode.  However, using this method there
  178. ; is no way to specify the values of the real mode SEGMENT registers.
  179. ; Some of the VESA calls require ES:DI to point to buffers and so
  180. ; we need to use INT31h AX=300h service to call a real mode interrupt.
  181. ; The procedure below does exactly that...
  182. ;
  183. ;------------------------------------------------------------
  184. DOSinterrupt PROC
  185.         push    dword ptr 0             ; ignore  SS, SP
  186.         lea     esp,[esp - 8]           ; ignore  CS, IP ,FS, GS
  187.         push    [DOS_segs]              ; push DS and ES
  188.         pushfw
  189.         pushad
  190.         mov     edi,esp
  191.         mov     ax,0300h
  192.         xor     cx,cx
  193.         movzx   Ebx,Byte Ptr [esp+36h]  ; Get int number from stack param
  194.         int     31h                     ; Emulate Real Mode Interrupt
  195.         popad
  196.         popfw
  197.         pop     [DOS_segs]              ; get DS and ES
  198.         lea     esp,[esp+12]            ; Ignore SS,SP,CS,IP,FS,GS
  199.         ret     4                       ; return ingnoring parameter
  200. DOSinterrupt ENDP
  201.  
  202.  
  203.  
  204. ;
  205. ;  VBE Function 06h - Set/Get Logical Scan Line Length
  206. ;
  207. VbeFunc06 PROC
  208.           mov  ax,4F06h
  209.           int  10h
  210.           cmp  ah,00h
  211.           jne  @@J1
  212.           mov  Word Ptr [VBE_BytesPerScanLine],BX
  213. @@J1:     ret
  214. VbeFunc06 ENDP
  215.  
  216.  
  217.  
  218.  
  219.  
  220. CheckVbeMode PROC
  221.  
  222. ; Some of the vesa bios functions require a transfer of data in the
  223. ; real mode address space. The best way to do this is by taking advantage
  224. ; of the 8Kb file buffer initally setup by DOS32. As explained in the API.DOC
  225. ; this 8Kb buffer is in the real mode address space and may be use to temporary
  226. ; hold information.
  227. ;
  228.          pushad
  229.          mov    VideoModeNumber,ax
  230.  
  231.          mov    ax,0EE02h       ; GET REAL MODE SEGMENT OF FILE I/O BUFFER
  232.          int    31h
  233.  
  234.          ; returns AX = real mode segment of 8Kb buffer.
  235.          ;         EBX = program linear base address.
  236.  
  237.          mov    ProgramBaseAddress,ebx
  238.          mov    Real_ES,ax
  239.          And    Eax,0FFFFh
  240.          shl    Eax,4
  241.          sub    eax,ebx
  242.          Mov    file_buffer,eax     ; save near address of 8Kb file buffer.
  243.  
  244.  
  245.      ;
  246.      ;  GET VESA INFORMATION
  247.      ;
  248.          mov    ax,4F00h
  249.          mov    di,0            ; (real mode) ES:DI -> 256 byte buffer
  250.          push   10h
  251.          call   DOSinterrupt
  252.          Cmp    AX,004Fh
  253.          jne    NoVESA
  254.  
  255.  
  256.      ;
  257.      ; Search video mode list for 640x480x256 ( VESA mode 101h )
  258.      ; The vesa driver Func 4F00h fills in the buffer with the information.
  259.      ; Offset 0Eh of this buffer contains a real mode SEG:OFS of the video
  260.      ; mode list. This list consists of each supported VESA mode and
  261.      ; terminates with 0FFFFh.
  262.      ;
  263.          mov    EBP,[file_buffer]                       ; save video mem size
  264.          mov    dx,[ VbeInfoBlock.TotalMemory + EBP]
  265.          mov    [Total64Kbocks],dx
  266.  
  267.  
  268.      ; Get the real mode far pointer of the video mode list and
  269.      ; convert the real mode SEG:OFS address into a 32bit near pointer.
  270.      ;
  271.          Movzx edx,Word Ptr [ VbeInfoBlock.VideoModePtr + EBP + 2]
  272.          shl   edx,4
  273.          sub   edx,ProgramBaseAddress
  274.          Movzx ebx,Word Ptr [ VbeInfoBlock.VideoModePtr + EBP ]
  275.          add   edx,ebx                      ; EDX points to video mode list.
  276.          mov   bx,VideoModeNumber
  277.          and   bx,0111111111b               ; read bits 0..8
  278.          xor eax,eax
  279. Loop01:  Mov   ax,[Edx]                     ; Read video mode from list
  280.          Cmp   Ax,0FFFFh
  281.          je  @@ModeNotFound
  282.          add   Edx,2
  283.          cmp   Ax,Bx
  284.          jne   Loop01
  285.  
  286.  
  287.      ;
  288.      ; Get VBE MODE information
  289.      ; Note, the mode information block is also stored in the file buffer
  290.      ;
  291.         mov    ax,4F01h
  292.         mov    cx,VideoModeNumber
  293.         and    cx,0111111111b               ; read bits 0..8
  294.         mov    di,0                         ; ES:DI -> 256 byte buffer
  295.         push   10h
  296.         call   DOSinterrupt
  297.         Cmp    AX,004Fh
  298.         jne   ModeNotGood
  299.  
  300.  
  301.         Mov    EBP,file_buffer              ; EBP -> ModeInfoBlock
  302.  
  303.  
  304.      ;
  305.      ; Determine to use windowing or linear memory mapping.
  306.      ;
  307.         test    VideoModeNumber,0100000000000000b
  308.         jz      DoWithBanks
  309.  
  310.  
  311.  ; ******************************************************
  312.  ; Setup for linear memory mapping mode.
  313.  ; ******************************************************
  314.         Test   [ ModeInfoBlock.ModeAttributes + EBP],10000000b
  315.         jz     ModeNotGood
  316.      ;
  317.      ; Calulate a near pointer to physical linear mapping address.
  318.      ;
  319.          Mov    ebx,[ ModeInfoBlock.PhysBasePtr + EBP]
  320.          Mov    eax,[Old_PhysBasePtr]
  321.          cmp    eax,ebx
  322.          je     Jskip06
  323.          mov    [Old_PhysBasePtr],ebx
  324.          mov    cx,bx
  325.          shr    ebx,16
  326.          mov    si,Total64Kbocks
  327.          xor    edi,edi
  328.          mov    ax,0800h                ; map physical memory
  329.          int    31h
  330.          jc     ModeNotGood
  331.          shl    ebx,16
  332.          mov    bx,cx
  333.          mov    eax,ebx                 ; eax = linear address
  334. Jskip06:
  335.          mov    [esp+4*7],eax           ; save eax in stack
  336.          jmp    Finished
  337.  
  338.  
  339. DoWithBanks:
  340.  
  341.  ; ******************************************************
  342.  ; Setup for windowing mode.
  343.  ; ******************************************************
  344.  
  345.      ; check is windowing is avalible ( writable and availible )
  346.      ;
  347.         Test   [ ModeInfoBlock.ModeAttributes + EBP],01000000b
  348.         jnz   ModeNotGood
  349.         Mov    bl,[ ModeInfoBlock.WinAAttributes + EBP]
  350.         and    bl,0000101b
  351.         cmp    bl,0000101b
  352.         jne   ModeNotGood
  353.  
  354.     ;
  355.     ; Setup Bank Numbering table
  356.     ;
  357.         Movzx  eax,[ ModeInfoBlock.WinSize + EBP]
  358.         Movzx  ebx,[ ModeInfoBlock.WinGranularity + EBP]
  359.         xor    edx,edx
  360.         div    ebx
  361.         xor    edx,edx
  362.         xor    ecx,ecx
  363. @@loop01:
  364.         mov    _BankSetTable[ECX*4],edx
  365.         add    edx,eax
  366.         inc    ecx
  367.         cmp    ecx,LENGTH _BankSetTable
  368.         jb     @@loop01
  369.  
  370.  
  371.      ;
  372.      ; Calulate 32bit linear pointer to CPU video memory WindowA
  373.      ;
  374.          Movzx  eax,[ ModeInfoBlock.WinASegment + EBP]
  375.          shl    eax,4
  376.          mov    [esp+4*7],eax           ; save eax in stack
  377.  
  378.  
  379. Finished:
  380.  
  381.  
  382.     ;
  383.     ; If 32bit VBE inteface is availible then use the bloody thing
  384.     ;
  385.         mov    ax,4F0Ah
  386.         mov    BL,0                 ; return pmode interface
  387.         push   10h
  388.         call   DOSinterrupt
  389.         Cmp    AX,004Fh
  390.         jne    No32bitInterface
  391.         movzx  Esi,Real_ES              ; convert ES:DI to 32bit near ptr
  392.         shl    esi,4
  393.         and    edi,0ffffh
  394.         add    esi,edi
  395.         sub    esi,ProgramBaseAddress     ; ESI -> protected mode table.
  396.  
  397.      ; Use protected mode bank proc only for zero length memory list.
  398.      ;
  399.         movzx  edi,Word Ptr [ESI+06]      ; get port/memory table list
  400.         and    edi,edi
  401.         jz     @@usePmodeBanks
  402. @@L5:   cmp    Word Ptr [ESI+EDI],0FFFFh  ; search port list
  403.         lea    edi,[edi+2]
  404.         jne @@L5
  405.         cmp    Word Ptr [ESI+EDI],0FFFFh  ; see if mem list is zero
  406.         jne    @@SkipPmodeBanks
  407.  
  408. @@usePmodeBanks:
  409.         movzx  eax,Word Ptr [ESI+00]
  410.         add    eax,esi
  411.         mov    [VbeSetBank],eax         ; save Set Bank code address.
  412.  
  413. @@SkipPmodeBanks:
  414.  
  415.  
  416.       ; Save Set display start code address.
  417.       ;
  418.         movzx  eax,Word Ptr [ESI+02]
  419.         add    eax,esi
  420.         mov    [PmodeSetStart],eax
  421.         mov    [VbeSetStart],Offset SetStart_ProtectedMode
  422.  
  423.  
  424.       ; Get bytes per scan line for the protected mode SetStart function.
  425.       ;
  426.         mov    ax,[ ModeInfoBlock.BytesPerScanLine + EBP]
  427.         mov    Word Ptr [VBE_BytesPerScanLine],ax
  428.  
  429.  
  430.       ; adjust for plane boundary for 8 bit+ modes
  431.       ;
  432.         mov    [VBE_StarPerPixelFactor],0
  433.         Cmp    [ ModeInfoBlock.BitsPerPixel + EBP],4
  434.         je @@1
  435.         mov    [VBE_StarPerPixelFactor],2
  436. @@1:
  437.  
  438.  
  439. No32bitInterface:
  440.  
  441.  
  442.          mov    eax,ProgramBaseAddress  ; convert linear pointer to near
  443.          sub    [esp+4*7],eax
  444.          popad
  445.          clc
  446.          ret
  447.  
  448.  
  449.  
  450. ;------------------------ Error messages ---------------------------------
  451. ModeNotGood:
  452.          popad
  453.          mov dl,3
  454.          jmp Abort
  455.  
  456. @@ModeNotFound:
  457.          popad
  458.          mov dl,2
  459.          jmp Abort
  460.  
  461. NoVESA:
  462.          popad
  463.          mov dl,1
  464.  
  465. Abort:
  466.          xor  eax,eax
  467.          stc
  468.          ret
  469.  
  470. CheckVbeMode ENDP
  471.  
  472.  
  473.  
  474. SetVbeMode PROC
  475.      ;
  476.      ; Set VIDEO mode
  477.      ;
  478.          pushad
  479.          xor    eax,eax
  480.          xor    ebx,ebx
  481.          xor    ecx,ecx
  482.          xor    edx,edx
  483.          mov    BX,VideoModeNumber
  484.          mov    ax,4F02h
  485.          Int    10h
  486.          popad
  487.          Ret
  488. SetVbeMode ENDP
  489.  
  490.  
  491.  
  492. End
  493.